<?php

namespace app\controller\admin\module\auth;

use app\controller\admin\module\AdminBaseController;
use think\exception\ValidateException;
use think\response\Json;

/**
 * 权限管理
 * @auth-name 权限管理
 * @auth-alias auth
 */
class Index extends AdminBaseController
{
    protected string $modelName = 'auth';

    public function index(){
        $role = Model('gadmin')->getList([], 'id, name');
        unset($role[0]);
        $list = $this->getList();
        $gid = values('gid', 0);
        if($gid > 0){
            $midx = $this->model->getList(['gid' => $gid], 'gid, mid');
            if(!empty($midx)){
                $condition = ['id' => array_filter(array_unique(array_column($midx, 'mid')))];
                $myList = $this->getList($condition);
                foreach($myList as $k => $v){
                    $list[$k]['checked'] = true;
                }
            }
        }
        return fetch('/admin/auth/index', [
            'role' => $role,
            'html' => $this->getHtml(infiniteCategoryChild($list))
        ]);
    }

    private function getHtml($arr, $level = 1, $pid = 0){
        $html = $level == 3 ? '<tr><td class="ps-lg-5"><div class="collapse" id="auth-' . $pid . '">' : '';
        foreach($arr as $v){
            if($v['level'] != 3 and (!isset($v['child']) or empty($v['child']))){
                continue;
            }
            if($v['level'] == 1){
                $html .= '<tr><td class="padding-null"></td></tr>';
            }
            $dataID = $pid . '-' . $v['id'];
            if(in_array($v['level'], [1, 2])){
                $html .= '<tr>';
                $html .= '    <td class="' . ($v['level'] == 2 ? 'ps-lg-4' : '') . '">';
                $html .= '        <div class="d-flex">';
                $html .= '            <div class="form-check">';
                $html .= '                <input class="form-check-input checkbox-child" name="pmid[]" type="checkbox" id="roleid-1-' . $dataID . '" dataid="id-1-' . $dataID . '" value="' . $v['id'] .'" ' . ((isset($v['checked']) and $v['checked'] === true) ? 'checked' : '') . '>';
                $html .= '                <label class="form-check-label" for="roleid-1-' . $dataID . '">' . $v['name'] . '</label>';
                $html .= '            </div>';
                $html .= $v['level'] == 2 ? '<div class="flex-grow-1" data-bs-toggle="collapse" role="button" aria-expanded=\'false\' data-bs-target="#auth-' . $dataID . '"></div>' : '';
                $html .= '        </div>';
                $html .= '    </td>';
                $html .= '</tr>';
            }else{
                $html .= '<div class="form-check">';
                $html .= '    <input class="form-check-input checkbox-child" type="checkbox" name="mid[]" id="roleid-1-' . $dataID . '" dataid="id-1-' . $dataID . '" value="' . $v['id'] .'" ' . ((isset($v['checked']) and $v['checked'] === true) ? 'checked' : '') . '>';
                $html .= '    <label class="form-check-label" for="roleid-1-' . $dataID . '">' . $v['name'] . '</label>';
                $html .= '</div>';
            }
            $html .= $this->getHtml($v['child'], $v['level'] + 1, $dataID);
        }
        $html .= $level == 3 ? '</div></td></tr>' : '';
        return $html;
    }

    private function getList($condition = []): array
    {
        $arr = Model('menu')->getPageList($condition, 'id, icon, name, controller, controller_alias, method, method_alias, request_method, pid, level, sort, is_home_page, show, status');
        if(empty($arr['rows'])){
            return [];
        }
        array_multisort(array_column($arr['rows'], 'is_home_page'), SORT_DESC, array_column($arr['rows'], 'level'), SORT_ASC,  array_column($arr['rows'], 'sort'), SORT_DESC, $arr['rows']);
        if($arr['rows'][0]['is_home_page'] == 1)unset($arr['rows'][0]);
        return array_column($arr['rows'], null, 'id');
    }

    /**
     * 获取角色权限
     * @auth-name 获取角色权限
     * @auth-alias roleauth
     * @return Json
     */
    public function getRoleAuth(){
        $list = [];
        $gid = values('gid', 0);
        if(!empty($gid)){
            $list = $this->model->getList(['gid' => $gid], 'gid, mid');
        }
        return responseMsg('获取成功', 200, $list);
    }

    /**
     * 保存
     * @auth-name 保存
     * @auth-alias save
     * @auth-request-method post
     * @return Json
     */
    public function save(){
        $gid = values('gid');   //角色名
        if(empty($gid)){
            return responseMsg('缺少参数');
        }
        $info = Model('gadmin')->getInfo(['id' => $gid]);
        if(empty($info)){
            return responseMsg('未找到该角色信息');
        }
        $pmid = values('pmid', []);   //权限
        $mid = values('mid', []);   //权限
        $mid = (array)array_merge($pmid, $mid);
        try {
            $this->validate([
                'mid' => $mid,
            ],[
                'mid|权限' => ['require'],
            ]);

            $myMid = $this->model->getList(['gid' => $gid], 'mid');
            $oldMid = !empty($myMid) ? array_column($myMid, 'mid') : [];
            [$create, $delete] = $this->handlerMid($oldMid, $mid);
            if(empty($create) and empty($delete)){
                throw new ValidateException('权限未改变');
            }
            if(!empty($create)){
                $data = [];
                foreach($create as $v){
                    $data[] = [
                        'gid' => $gid,
                        'mid' => $v,
                        'addtime' => time(),
                    ];
                }
                $res = $this->model->addAll($data);
                if(!$res){
                    throw new ValidateException('新增失败');
                }
            }
            if(!empty($delete)){
                if(!$this->model->del(['gid' => $gid, 'mid' => $delete])){
                    throw new ValidateException('删除失败');
                }
            }
            putAdminLog("更新角色[{$gid}]的权限");
            return responseMsg('更新成功', 200);
        }catch (ValidateException $e){
            return responseMsg($e->getError());
        }
    }


    private function handlerMid($old, $new): array
    {
        sort($old);
        sort($new);
        $create = $delete = [];
        if($old != $new) {
            if (empty($new)) {
                $delete = $old;
            } else if (empty($old)) {
                $create = $new;
            } else {
                foreach ($new as $v) {
                    if (!in_array($v, $old)) {
                        $create[] = $v;
                    }
                }
                foreach ($old as $v) {
                    if (!in_array($v, $new)) {
                        $delete[] = $v;
                    }
                }
            }
        }
        return [$create, $delete];
    }

}